package com.yeskery.nut.event;

import com.yeskery.nut.core.NutException;

import java.lang.reflect.Method;
import java.lang.reflect.Parameter;

/**
 * 代理智能事件监听器
 * @author Yeskery
 * 2023/8/9
 */
public class ProxySmartApplicationListener implements SmartApplicationListener {

    /** 支持的事件类型 */
    private final Class<? extends ApplicationEvent> type;

    /** 顺序值 */
    private final int order;

    /** 目标对象 */
    private final Object target;

    /** 目标方法 */
    private final Method method;

    /**
     * 构建代理智能事件监听器
     * @param type 支持的事件类型
     * @param order 顺序值
     * @param target 目标对象
     * @param method 目标方法
     */
    public ProxySmartApplicationListener(Class<? extends ApplicationEvent> type, int order, Object target, Method method) {
        this.type = type;
        this.order = order;
        this.target = target;
        this.method = method;
    }

    @Override
    public int getOrder() {
        return order;
    }

    @Override
    public void onApplicationEvent(ApplicationEvent event) {
        try {
            Parameter[] parameters = method.getParameters();
            if (parameters.length == 0) {
                this.method.invoke(target);
                return;
            }
            if (parameters.length > 1) {
                throw new NutException("@EventListener Method Only Support No Parameter Or One Parameter For Type ApplicationEvent.");
            }
            Object[] variables = new Object[1];
            if (parameters[0].getType().isAssignableFrom(event.getClass())) {
                variables[0] = event;
            } else {
                variables[0] = null;
            }
            this.method.invoke(target, variables);
        } catch (Exception e) {
            throw new NutException("@EventListener Method Execute Fail.", e);
        }
    }

    @Override
    public boolean supportEventType(Class<? extends ApplicationEvent> eventType) {
        return type.isAssignableFrom(eventType);
    }
}
